#pragma once

#include "Mathematica.h"
#include <cmath>
#include <random>

namespace congruent_packing
{

template<class nesting_problem_t>
class SA_objective_t
{
public:
	SA_objective_t( nesting_problem_t & _nesting_info )
	: nesting_info( _nesting_info )
	{}

	bool operator()(const PointF & point, size_t index, double T)
	{
		double oldValue = Mathematica::minDistance2Point( index, nesting_info.points[index], nesting_info.points );
		double newValue = Mathematica::minDistance2Point( index, point, nesting_info.points );
		double delta = oldValue - newValue;

		if (delta < 0)
		{
			return true;
		}

		double inv_T = 1.0 / T;
		double r =  real_distr(rand_engine);
		double E = exp( -delta * inv_T );
		bool result = r <= E;
		return result;
	}

private:
	nesting_problem_t & nesting_info;
	std::uniform_real_distribution<> real_distr;
	std::default_random_engine rand_engine;
};

}